// 1.导入相关插件
import Vue from "vue";
import VueRouter from "vue-router"; 

// import Home from "./../components/Home";
// import Mine from "./../components/Mine";

// 使用路由懒加载
let Home=()=> import("./../components/Home");
let Mine=()=> import("./../components/Mine");
let one=()=> import("./../components/one");
let two=()=> import("./../components/two");


// 2.通过Vue.use方法安装VueRouter插件
Vue.use(VueRouter);

let routes=[
  {
    path:"/",
    redirect:"/home"//重定向
  },

  {
    path:"/home",
    component:Home,
    children:[
      {
        path:"/",
        redirect:"one"//重定向
      },
      {
        path:"one",
        // 注意：以/开头的嵌套路径会被当成根路径
        component:one
      },
      {
        path:"two",
        component:two
      },
    ],
    // 原数据
    meta:{
      title:"首页"
    }
  },
  {
    path:"/Mine/:userId",
    component:Mine,
    // 原数据
    meta:{
      title:"我的"
    }
  }
]

// 3.实例化router对象
let router=new VueRouter({
  // 配置路由和组件之间的映射关系
  routes,
  // mode:"history", //使用history的方式实现路由，默认是使用push方法，插入历史记录
  linkActiveClass:"active",//修改组件激活时的类名

})

router.beforeEach(function(to,from,next){
  document.title=to.matched[0].meta.title;
  next();

})

// 4.将router对象导出，然后导入到Vue实例化对象中
export default router;

// 缓存原来的 push 方法
const originalPush = VueRouter.prototype.push
//指定新的push方法
VueRouter.prototype.push = function (location, onResolve, onReject) {
  //制定了一个成功或者失败的回调
    if (onResolve || onReject) {
        //直接调用原来的 push 方法
        // originalPush(location, onResolve, onReject)  
        //这里使用 call 可以直接指定当前的 router 对象，要是没有这个就会默认是window 对象，启用严格模式之后就是 undefined
        return originalPush.call(this, location, onResolve, onReject)
    }
    //如果没有指明一个成功或者失败的回调，需要使用到catch处理
    return originalPush.call(this, location).catch((err) => {
        //如果是重复导航所引起的错误的话
        if (VueRouter.isNavigationFailure(err)) {
            //这个 return err 返回的是成功的 Promise，其中Promise的value是 err
            return err
        }
        //如果是其他的错误就会接着往下传
        return Promise.reject(err)
    })
}


//缓存原来的replace 方法
const originalReplace = VueRouter.prototype.replace
//指定了一个新的 replace 方法
VueRouter.prototype.replace = function (location, onResolve, onReject) {
    if (onResolve || onReject) {
        return originalReplace.call(this, location, onResolve, onReject)
    }
    return originalReplace.call(this, location).catch((err) => {
        if (VueRouter.isNavigationFailure(err)) {
            return err
        }
        return Promise.reject(err)
    })
}

router.onError((error) => {
  const pattern = /Loading chunk (\d)+ failed/g;
  const isChunkLoadFailed = error.message.match(pattern);
  if(isChunkLoadFailed){
    // 用路由的replace方法，并没有相当于F5刷新页面，失败的js文件并没有从新请求，会导致一直尝试replace页面导致死循环，而用 location.reload 方法，相当于触发F5刷新页面，虽然用户体验上来说会有刷新加载察觉，但不会导致页面卡死及死循环，从而曲线救国解决该问题
      location.reload();
      // const targetPath = $router.history.pending.fullPath;
      // $router.replace(targetPath);
  }
  
});

